package com.api.volunteer.service.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectResult;
import com.api.volunteer.model.*;
import com.api.volunteer.repository.AccountPhotoRepository;
import com.api.volunteer.repository.AccountRepository;
import com.api.volunteer.repository.UserRepository;
import com.api.volunteer.service.AccountService;
import com.api.volunteer.service.SubcribeMessageService;
import com.api.volunteer.util.Holder;
import com.api.volunteer.util.Result;
import com.api.volunteer.vo.AccountVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.io.InputStream;
import java.util.Objects;
import java.util.Optional;

/**
 * @author 邹宇杰
 * @email 2901570623@qq.com
 * @date 2022/3/31 16:12
 */
@Service("accountService")
@Transactional(rollbackOn = Exception.class)
public class AccountServiceImpl implements AccountService {

    @Autowired
    AccountRepository accountRepository;

    @Autowired
    UserRepository userRepository;

    @Autowired
    AccountPhotoRepository accountPhotoRepository;

    @Autowired
    Holder holder;

    @Autowired
    OSS oss;

    @Autowired
    SubcribeMessageService subcribeMessageService;

    @Value("${aliyun.oss.bucketName}")
    String bucketName;

    final String callbackUrl = "https://%s.%s/%s";

    @Value("${aliyun.oss.endpoint}")
    public String endpoint;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    private final Logger logger = LoggerFactory.getLogger(LoginTokenServiceImpl.class);

    @Override
    public void save(AccountVo accountVo) throws InterruptedException {

        Account account = new Account();

        account.setOpenid(holder.getUser().getOpenid());

        Account accountByOpenid = accountRepository.findAccountByOpenid(account.getOpenid());

//        Optional.ofNullable(accountByOpenid).orElseGet(() -> {
//            BeanUtils.copyProperties(accountVo, account);
//            UserEntity userEntity = userRepository.findUserEntityByOpenid(holder.getUser().getOpenid());
//            userEntity.setThirdSubmit(Status.Seccess);
//            userRepository.save(userEntity);
//            Account acc = accountRepository.save(account);
//            for (String schoolPicture : accountVo.getSchoolPictures()) {
//                AccountPhoto accountPhoto = new AccountPhoto();
//                accountPhoto.setAccountId(acc.getId());
//                accountPhoto.setPicture(schoolPicture);
//                accountPhotoRepository.save(accountPhoto);
//            }
//            return acc;
//        });

        if(accountByOpenid == null){
            BeanUtils.copyProperties(accountVo, account);
            UserEntity userEntity = userRepository.findUserEntityByOpenid(holder.getUser().getOpenid());
            userEntity.setThirdSubmit(Status.Seccess);
            userRepository.save(userEntity);
            if (Objects.equals(account.getAccountSource(), AccountSource.EMPLOYER)) {
                account.setStatus(Status.Auditing);
                subcribeMessageService.sendAuditMessage(holder.getUser().getOpenid());
            }
            Account acc = accountRepository.save(account);

            if(accountVo.getSchoolPictures() != null && !accountVo.getSchoolPictures().isEmpty()){
                for (String schoolPicture : accountVo.getSchoolPictures()) {
                    AccountPhoto accountPhoto = new AccountPhoto();
                    accountPhoto.setAccountId(acc.getId());
                    accountPhoto.setPicture(schoolPicture);
                    accountPhotoRepository.save(accountPhoto);
                }
            }

        }else{

            BeanUtils.copyProperties(accountVo, accountByOpenid);

            Account save = accountRepository.save(accountByOpenid);

            if(Objects.equals(accountByOpenid.getAccountSource(), AccountSource.EMPLOYER)){
                accountByOpenid.setStatus(Status.Auditing);
                accountRepository.save(accountByOpenid);
                System.out.println(1);
                subcribeMessageService.sendAuditMessage(holder.getUser().getOpenid());
            }

            UserEntity userEntity = userRepository.findUserEntityByOpenid(holder.getUser().getOpenid());
            userEntity.setThirdSubmit(Status.Seccess);
            userRepository.save(userEntity);

            accountPhotoRepository.deleteAccountPhotoByAccountId(save.getId());

            if(accountVo.getSchoolPictures() != null && !accountVo.getSchoolPictures().isEmpty()){
                for (String schoolPicture : accountVo.getSchoolPictures()) {
                    AccountPhoto accountPhoto = new AccountPhoto();
                    accountPhoto.setAccountId(save.getId());
                    accountPhoto.setPicture(schoolPicture);
                    accountPhotoRepository.save(accountPhoto);
                }
            }
        }


    }

    @Override
    public Result upload(String imageName, InputStream ins) {
        Result result = new Result();
        PutObjectResult putObjectResult = null;
        try {
            putObjectResult = oss.putObject(bucketName, imageName, ins);
        } catch (OSSException e) {
            logger.error(e.getMessage());
        } catch (ClientException e) {
            logger.error(e.getMessage());
        }
        if(!Optional.ofNullable(putObjectResult).orElseThrow(()->{return new RuntimeException("上传失败");}).getETag().isEmpty()){
            result.put("code",200).put("message", String.format(callbackUrl, bucketName, endpoint, imageName));
        }else{
            result.put("code", 400).put("message", "上传失败");
        }
        return result;
    }

    @Override
    public void audit(String openid) {

        Account accountByOpenid = accountRepository.findAccountByOpenid(openid);

        Optional.ofNullable(accountByOpenid).orElseThrow(()->{
            return new RuntimeException("当前用户不存在");
        }).setStatus(Status.AuditSuccess);

        subcribeMessageService.sendAuditMessage(openid);

        accountRepository.save(accountByOpenid);

    }
}
